﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 目标标本：4.0.30319.239
 * 
 * 最后修改：2011/12/16 17:53:10
 * ************************************************************/
namespace Mozlite.Web.UI
{
    using System;
    using System.Linq;
    using System.Text;
    using System.Web.Mvc;
    using System.Web.Routing;
    using System.Collections.Generic;
    using Mozlite.Common;
    using WebRoute = Mozlite.Common.Route;
    using SysRoute = System.Web.Routing.Route;

    /// <summary>
    /// 路由扩展方法类。
    /// </summary>
    public static class RouteUtility
    {
        /// <summary>
        /// 注册区域路由。
        /// </summary>
        /// <param name="context">对在 ASP.NET MVC 应用程序内注册某个区域时所需的信息进行封装。</param>
        public static void BeginRegister(this AreaRegistrationContext context)
        {
            Dictionary<string, WebRoute> routes;
            if (Routes.LoadRoutes().TryGetValue(context.AreaName, out routes))
            {
                foreach (var route in routes)
                {
                    context.Routes.Add(RouteManager.GetRouteName(context.AreaName, route.Key), new SysRoute(RouteManager.Replace(route.Value.Url, context.AreaName), WebRoute.FromString(route.Value.Defaults), WebRoute.FromString(route.Value.Constraints), new RouteValueDictionary { 
                    { "Namespaces", context.Namespaces.ToArray<string>() },
                    { "Area", context.AreaName}
                    }, route.Value.RouteHandler));
                }
            }
        }

        /// <summary>
        /// 注册路由。
        /// </summary>
        /// <param name="routes">路由集合。</param>
        public static void BeginRegister(this RouteCollection routes)
        {
            Dictionary<string, WebRoute> urls;
            if (Routes.LoadRoutes().TryGetValue(Routes.NullArea, out urls))
            {
                foreach (var route in urls)
                {
                    routes.Add(route.Key, new SysRoute(RouteManager.Replace(route.Value.Url), WebRoute.FromString(route.Value.Defaults), WebRoute.FromString(route.Value.Constraints), route.Value.RouteHandler));
                }
            }
        }

        /// <summary>
        /// 注册路由。
        /// </summary>
        /// <param name="routes">路由集合。</param>
        /// <param name="name">名称，唯一</param>
        /// <param name="url">Url地址。</param>
        /// <param name="defaults">默认值。</param>
        /// <param name="constraints">正则表达式。</param>
        /// <param name="namespaces">命名空间。</param>
        public static void Register(this RouteCollection routes, string name, string url = null, object defaults = null, object constraints = null, string[] namespaces = null)
        {
            if (namespaces == null)
                namespaces = new[] { "Mozlite.Web.UI.Controllers" };
            if (defaults == null)
                defaults = new { controller = "home", action = "Index", id = UrlParameter.Optional };
            routes.MapRoute(RouteManager.GetRouteName(Routes.NullArea, name), RouteManager.Replace(url), defaults, constraints, namespaces);
        }

        /// <summary>
        /// 注册路由。
        /// </summary>
        /// <param name="routes">路由集合。</param>
        /// <param name="name">名称，唯一</param>
        /// <param name="url">Url地址。</param>
        /// <param name="defaults">默认值。</param>
        /// <param name="constraints">正则表达式。</param>
        /// <param name="namespaces">命名空间。</param>
        public static void EndRegister(this RouteCollection routes) {
            routes.MapRoute(RouteManager.GetRouteName(Routes.NullArea, "Index"), "{controller}", new { controller = "home", action = "Index"}, null, new[] { "Mozlite.Web.UI.Controllers" });
        }

        /// <summary>
        /// 注册区域路由。
        /// </summary>
        /// <param name="context">区域注册上下文。</param>
        /// <param name="name">唯一键。</param>
        /// <param name="url">Url地址。</param>
        /// <param name="defaults">默认值。</param>
        /// <param name="constraints">正则表达式。</param>
        /// <param name="namespaces">命名空间集合。</param>
        /// <param name="ignoreSubDomain">忽略二级域名。</param>
        public static void Register(this AreaRegistrationContext context, string name, string url = null, object defaults = null, object constraints = null, string[] namespaces = null, bool ignoreSubDomain = false)
        {
            if (namespaces == null)
                namespaces = context.Namespaces.ToArray<string>();
            if (defaults == null)
                defaults = new { controller = "home", action = "Index", id = UrlParameter.Optional };
            var configuration = Applications.GetApplication(context.AreaName).GetConfiguration();
            if (!ignoreSubDomain && !string.IsNullOrEmpty(configuration.Domain))
                context.Routes.Add(RouteManager.GetRouteName(context.AreaName, name), new DomainRoute(configuration.Domain, RouteManager.Replace(url), defaults, new RouteValueDictionary(constraints), new RouteValueDictionary { 
                    { "Namespaces", namespaces },
                    { "Area", context.AreaName}
                    }));
            else
                context.MapRoute(RouteManager.GetRouteName(context.AreaName,  name), RouteManager.Replace(url, context.AreaName), defaults, constraints, namespaces);
        }
        
        /// <summary>
        /// 注册首页路由。
        /// </summary>
        /// <param name="context">区域注册上下文。</param>
        /// <param name="ignoreSubDomain">忽略二级域名。</param>
        public static void EndRegister(this AreaRegistrationContext context, bool ignoreSubDomain = false)
        {
            var configuration = Applications.GetApplication(context.AreaName).GetConfiguration();
            if (!ignoreSubDomain && !string.IsNullOrEmpty(configuration.Domain))
                context.Routes.Add(RouteManager.GetRouteName(context.AreaName, "Index"), new DomainRoute(configuration.Domain, "{controller}", new { controller = "home", action = "Index" }, null, new RouteValueDictionary { 
                    { "Namespaces", context.Namespaces.ToArray<string>() },
                    { "Area", context.AreaName}
                    }));
            else
                context.MapRoute(RouteManager.GetRouteName(context.AreaName, "Index"), context.AreaName, new { controller = "home", action = "Index" }, null, context.Namespaces.ToArray<string>());
        }

        /// <summary>
        /// 注册路由。
        /// </summary>
        /// <param name="routes">路由集合。</param>
        /// <param name="controller">控制器。</param>
        /// <param name="action">行为。</param>
        /// <param name="applicationType">应用程序类型。</param>
        /// <param name="useControllerUrl">是否将控制器添加到路径里。</param>
        /// <param name="defaults">默认值。</param>
        /// <param name="constraints">正则表达式。</param>
        public static void RegisterControllerAction(this RouteCollection routes, string controller, string action, ApplicationType applicationType = ApplicationType.Common, bool useControllerUrl = true, object constraints = null, string[] namespaces = null)
        {
            string url = useControllerUrl ? controller + "/" : null;
            url += action;
            routes.Register(controller + "_" + action, url, new { controller = controller, action = action, applicationtype = applicationType }, constraints, namespaces);
        }

        /// <summary>
        /// 注册路由。
        /// </summary>
        /// <param name="context">路由注册上下文。</param>
        /// <param name="controller">控制器。</param>
        /// <param name="action">行为。</param>
        /// <param name="applicationType">应用程序类型。</param>
        /// <param name="defaults">默认值。</param>
        /// <param name="useControllerUrl">使用控制器为URL路径之一。</param>
        /// <param name="constraints">正则表达式。</param>
        /// <param name="namespaces">命名空间集合。</param>
        /// <param name="ignoreSubDomain">忽略二级域名。</param>
        public static void RegisterControllerAction(this AreaRegistrationContext context, string controller, string action, ApplicationType applicationType = ApplicationType.Common, bool useControllerUrl = true, object constraints = null, string[] namespaces = null, bool ignoreSubDomain = false)
        {
            string url = useControllerUrl ? controller + "/" : null;
            url = "$root:" + url + action;
            context.Register(controller + "_" + action, url, new { controller = controller, action = action, applicationtype = applicationType }, constraints, namespaces, ignoreSubDomain);
        }
    }
}